package com.sky.controller;

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.alibaba.fastjson.JSON;
import com.sky.result.Result;
import com.sky.service.user.OrderService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByOutTradeNoRequest;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;

@RestController
@Slf4j
public class WXPayController {

    @Autowired
    private Config config;
    @Autowired
    private NotificationConfig notificationConfig;
    @Autowired
    private OrderService orderService;


    /**
     * 模拟微信回调返回成功
     */
    @GetMapping("/paySuc")
    public void paySuccess(String num){
        log.info("模拟微信回调:{}订单号支付成功",num);
        orderService.paySuccess(num);
    }


    /**
     * 模拟用户催单
     */
    @GetMapping("/quickComp")
    public Result justDoIt(String num){
        orderService.toCompleteOrderFast(num);
        return Result.success();
    }


    /**
     * 微信回调通知
     *
     * @return
     */
    @PostMapping("/notify")
    public String payNotify(@RequestBody String body, HttpServletRequest request) {
        log.info("接收到微信回调消息");
        String wechatSignature = request.getHeader("Wechatpay-Signature");
        String wechatPaySerial = request.getHeader("Wechatpay-Serial");
        String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
        String wechatTimestamp = request.getHeader("Wechatpay-Timestamp");
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPaySerial)
                .nonce(wechatpayNonce)
                .signature(wechatSignature)
                .timestamp(wechatTimestamp)
                .body(body)
                .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(notificationConfig);
        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            String outTradeNo = transaction.getOutTradeNo();
            log.info("开始处理订单后续逻辑：{}", outTradeNo);
            // todo
        } catch (ValidationException e) {
            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).toString();
        }
        // 处理成功，返回 200 OK 状态码
        return ResponseEntity.status(HttpStatus.OK).toString();
    }

    @GetMapping("/pay")
    public Result pay() {
        NativePayService service = new NativePayService.Builder().config(config).build();
        // 构造参数
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(1);
        amount.setCurrency("CNY");
        request.setAmount(amount);
        request.setOutTradeNo("15566778899");
        request.setNotifyUrl("https://localhost/notify");
        request.setAppid("wx0ca99a203b1e9943");
        request.setMchid("1561414331");
        request.setDescription("好吃的鸡排");

        PrepayResponse response = service.prepay(request);
        String codeUrl = response.getCodeUrl();
        QrCodeUtil.generate(codeUrl, 500, 500, new File("D://jipai.png"));
        return Result.success();

    }

    @GetMapping("/refund")
    public String refund(String orderNo) {

        RefundService refundService = new RefundService.Builder().config(config).build();
        CreateRequest createRequest = new CreateRequest();
        // 设置退款参数
        createRequest.setOutTradeNo(orderNo);
        createRequest.setOutRefundNo(orderNo);
        AmountReq amountReq = new AmountReq();
        amountReq.setTotal(1L);
        amountReq.setRefund(1L);
        amountReq.setCurrency("CNY");
        createRequest.setAmount(amountReq);
        createRequest.setReason("取消订单退款");
        createRequest.setNotifyUrl("http://10bbcfd3.r12.cpolar.top/wxpay/refund/notify");
        // 发起退款
        Refund refund = refundService.create(createRequest);

        return JSON.toJSONString(refund);
    }

    //结果查询
 @GetMapping("/query")
 public String queryResult(String orderNo) {

     QueryOrderByOutTradeNoRequest orderByOutTradeNoRequest = new QueryOrderByOutTradeNoRequest();
     orderByOutTradeNoRequest.setMchid("1561414331");
     orderByOutTradeNoRequest.setOutTradeNo(orderNo);

     // 构建service
     NativePayService service = new NativePayService.Builder().config(config).build();

     try {
         Transaction result = service.queryOrderByOutTradeNo(orderByOutTradeNoRequest);
         return JSON.toJSONString(result);
     } catch (ServiceException e) {
         // API返回失败, 例如ORDER_NOT_EXISTS
         System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
         System.out.printf("reponse body=[%s]\n", e.getResponseBody());
         return e.getErrorMessage();
     }
 }
}
